/***********************************************************************
    filename:   CEGUIFalImagerySection.cpp
    created:    Mon Jun 13 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/

#include "renderers/ImagerySection.h"
#include "hgePropertyHelper.h"
#include <iostream>

ImagerySection::ImagerySection() :
    d_masterColours(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
    d_colourProperyIsRect(false)
{}

ImagerySection::ImagerySection(const String& name) :
    d_name(name),
    d_masterColours(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
    d_colourProperyIsRect(false)
{}

void ImagerySection::render(Window& srcWindow, const ColourRect* modColours, const hgeRect* clipper, bool clipToDisplay) const
{
    // decide what to do as far as colours go
    ColourRect finalCols;
    initMasterColourRect(srcWindow, finalCols);

    if (modColours)
        finalCols *= *modColours;

    ColourRect* finalColsPtr = (finalCols.isMonochromatic() && finalCols.d_top_left.getARGB() == 0xFFFFFFFF) ? 0 : &finalCols;

    // render all image components in this section
    for(ImageryList::const_iterator image = d_images.begin(); image != d_images.end(); ++image)
    {
        (*image).render(srcWindow, finalColsPtr, clipper, clipToDisplay);
    }
    // render all text components in this section
    for(TextList::const_iterator text = d_texts.begin(); text != d_texts.end(); ++text)
    {
        (*text).render(srcWindow, finalColsPtr, clipper, clipToDisplay);
    }
}

void ImagerySection::render(Window& srcWindow, const hgeRect& baseRect, const ColourRect* modColours, const hgeRect* clipper, bool clipToDisplay) const
{
    // decide what to do as far as colours go
    ColourRect finalCols;
    initMasterColourRect(srcWindow, finalCols);

    if (modColours)
        finalCols *= *modColours;

    ColourRect* finalColsPtr = (finalCols.isMonochromatic() && finalCols.d_top_left.getARGB() == 0xFFFFFFFF) ? 0 : &finalCols;

    // render all image components in this section
    for(ImageryList::const_iterator image = d_images.begin(); image != d_images.end(); ++image)
    {
        (*image).render(srcWindow, baseRect, finalColsPtr, clipper, clipToDisplay);
    }
    // render all text components in this section
    for(TextList::const_iterator text = d_texts.begin(); text != d_texts.end(); ++text)
    {
        (*text).render(srcWindow, baseRect, finalColsPtr, clipper, clipToDisplay);
    }
}

void ImagerySection::addImageryComponent(const ImageryComponent& img)
{
    d_images.push_back(img);
}

void ImagerySection::clearImageryComponents()
{
    d_images.clear();
}

void ImagerySection::addTextComponent(const TextComponent& text)
{
    d_texts.push_back(text);
}

void ImagerySection::clearTextComponents()
{
    d_texts.clear();
}

const ColourRect& ImagerySection::getMasterColours() const
{
    return d_masterColours;
}

void ImagerySection::setMasterColours(const ColourRect& cols)
{
    d_masterColours = cols;
}

const String& ImagerySection::getName() const
{
    return d_name;
}

void ImagerySection::setMasterColoursPropertySource(const String& property)
{
    d_colourPropertyName = property;
}

void ImagerySection::setMasterColoursPropertyIsColourRect(bool setting)
{
    d_colourProperyIsRect = setting;
}

void ImagerySection::initMasterColourRect(const Window& wnd, ColourRect& cr) const
{
    // if colours come via a colour property
    if (!d_colourPropertyName.empty())
    {
        // if property accesses a ColourRect
        if (d_colourProperyIsRect)
        {
            cr = PropertyHelper::stringToColourRect(wnd.getProperty(d_colourPropertyName));
        }
        // property accesses a colour
        else
        {
            colour val(PropertyHelper::stringToColour(wnd.getProperty(d_colourPropertyName)));
            cr.d_top_left     = val;
            cr.d_top_right    = val;
            cr.d_bottom_left  = val;
            cr.d_bottom_right = val;
        }
    }
    // use explicit ColourRect.
    else
    {
        cr = d_masterColours;
    }
}

hgeRect ImagerySection::getBoundingRect(const Window& wnd) const
{
    hgeRect compRect;
    hgeRect bounds(0, 0, 0, 0);

    // measure all imagery components
    for(ImageryList::const_iterator image = d_images.begin(); image != d_images.end(); ++image)
    {
        compRect = (*image).getComponentArea();	//.getPixelRect(wnd);

        bounds.d_left   = min(bounds.d_left, compRect.d_left);
        bounds.d_top    = min(bounds.d_top, compRect.d_top);
        bounds.d_right  = max(bounds.d_right, compRect.d_right);
        bounds.d_bottom = max(bounds.d_bottom, compRect.d_bottom);
    }
    // measure all text components
    for(TextList::const_iterator text = d_texts.begin(); text != d_texts.end(); ++text)
    {
        compRect = (*text).getComponentArea();	//.getPixelRect(wnd);

        bounds.d_left   = min(bounds.d_left, compRect.d_left);
        bounds.d_top    = min(bounds.d_top, compRect.d_top);
        bounds.d_right  = max(bounds.d_right, compRect.d_right);
        bounds.d_bottom = max(bounds.d_bottom, compRect.d_bottom);
    }

    return bounds;
}

hgeRect ImagerySection::getBoundingRect(const Window& wnd, const hgeRect& rect) const
{
    hgeRect compRect;
    hgeRect bounds(0, 0, 0, 0);

    // measure all imagery components
    for(ImageryList::const_iterator image = d_images.begin(); image != d_images.end(); ++image)
    {
        compRect = (*image).getComponentArea();	//.getPixelRect(wnd, rect);

        bounds.d_left   = min(bounds.d_left, compRect.d_left);
        bounds.d_top    = min(bounds.d_top, compRect.d_top);
        bounds.d_right  = max(bounds.d_right, compRect.d_right);
        bounds.d_bottom = max(bounds.d_bottom, compRect.d_bottom);
    }
    // measure all text components
    for(TextList::const_iterator text = d_texts.begin(); text != d_texts.end(); ++text)
    {
        compRect = (*text).getComponentArea();	//.getPixelRect(wnd, rect);

        bounds.d_left   = min(bounds.d_left, compRect.d_left);
        bounds.d_top    = min(bounds.d_top, compRect.d_top);
        bounds.d_right  = max(bounds.d_right, compRect.d_right);
        bounds.d_bottom = max(bounds.d_bottom, compRect.d_bottom);
    }

    return bounds;
}
